package org.bee.file;

import org.bee.exception.ExceptionUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.security.DigestInputStream;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

/**
 * 文件生成等一系列工具类
 */
public class FileUtils {
    static Logger logger = LoggerFactory.getLogger(FileUtils.class);

    /**
     * 在指定目录下创建文件并写入内容。
     *
     * @param directoryPath 目标目录的路径
     * @param fileName      要创建的文件名
     * @param content       要写入文件的内容
     */
    public static void createFileWithContent(String directoryPath, String fileName, String content) {
        // 构建文件路径
        Path filePath = Paths.get(directoryPath, fileName);
        // 检查并创建目录
        Path dirPath = filePath.getParent();
        try {
            if (Files.notExists(dirPath)) {
                Files.createDirectories(dirPath);
                // 写入内容到文件
                Files.write(filePath, content.getBytes(StandardCharsets.UTF_8));
            } else {
                // 写入内容到文件
                Files.write(filePath, content.getBytes(StandardCharsets.UTF_8));
            }
        } catch (IOException e) {
            logger.error("创建目录或写入文件时发生错误：{}", ExceptionUtils.getFullStackTrace(e));
        }
    }

    /**
     * 读文件到字符串
     * @param path 文件路径
     * @return 文件内容
     */
    public static String fileToString(String path)  {
        String result = null;
        StringBuilder stringBuilder = null;
        try (FileReader reader = new FileReader(path)) {
            stringBuilder = new StringBuilder();
            char[] buffer = new char[10];
            int size;
            while ((size = reader.read(buffer)) != -1) {
                stringBuilder.append(buffer, 0, size);
            }

        } catch (IOException e) {
            logger.error("读取文件发生异常：{}", ExceptionUtils.getFullStackTrace(e));
        }
        if (stringBuilder != null) {
            result = stringBuilder.toString();
        }
        return result;
    }

    /**
     * 删除文件
     * @param path 文件路径
     */
    public static void deleteFile(String path) {
        Path filePath = Paths.get(path);
        try {
            Files.delete(filePath);
        } catch (IOException e) {
            logger.error("删除文件发生异常：{}", ExceptionUtils.getFullStackTrace(e));
        }
    }

    /**
     * 删除文件夹及其下级文件
     * @param directory
     */
    public static void deleteDirectory(File directory) {
        if (directory.exists()) {
            File[] files = directory.listFiles();
            if (files != null) {
                for (File file : files) {
                    if (file.isDirectory()) {
                        deleteDirectory(file);
                    } else {
                        file.delete();
                    }
                }
            }
            directory.delete();
        }
    }

    /**
     * 计算上传文件的哈希值
     * @param is 文件输入流
     * @param algorithm 哈希算法（如 MD5, SHA-256）
     * @return 哈希值十六进制字符串，出错时返回null
     */
public static String getFileHash(InputStream is, String algorithm) {
    try {
        MessageDigest digest = MessageDigest.getInstance(algorithm);
        byte[] buffer = new byte[8192];

        try (DigestInputStream dis = new DigestInputStream(is, digest)) {
            while (dis.read(buffer) != -1) {
                // 自动更新哈希
            }
        }

        return bytesToHex(digest.digest());
    } catch (NoSuchAlgorithmException | IOException e) {
        logger.error("计算流哈希失败：{}", ExceptionUtils.getFullStackTrace(e));
        return null;
    }
}


    /**
     * 字节数组转十六进制字符串
     */
    private static String bytesToHex(byte[] bytes) {
        StringBuilder sb = new StringBuilder();
        for (byte b : bytes) {
            sb.append(String.format("%02x", b));
        }
        return sb.toString();
    }

    public static byte[] fileToBytes(String path) {
        byte[] bytes = null;
        try {
            bytes = Files.readAllBytes(Paths.get(path));
        } catch (IOException e) {
            logger.error("文件转字节数组失败：{}", ExceptionUtils.getFullStackTrace(e));
        }
        return bytes;
    }
}
